
package com.cortex.pineapple.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.cortex.pineapple.SpeechQuery;
import com.cortex.pineapple.R;
import com.cortex.pineapple.listener.SlidListener;
import com.cortex.pineapple.listener.SlidListener.OnSlidFingerListener;
import com.cortex.pineapple.listener.SlidListener.SlidDirection;
import com.cortex.pineapple.utilities.MessagesLog;
import com.cortex.pineapple.utilities.Utilities;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.text.Editable;
import android.text.Spannable;
import android.text.TextWatcher;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.DragEvent;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.View.OnFocusChangeListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ViewFlipper;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView.OnEditorActionListener;
import android.view.View.OnClickListener;

public class RowSearch extends RelativeLayout 
implements OnEditorActionListener,OnSlidFingerListener{

	private OnRunSearchListener onRunSearchListener;
	private OnTextChangedListener onTextChangedListener;
	private EditText rowSearch;
	private ImageView search,microphone;
	private ViewFlipper flipperSearch;
	private String lastSearch = "";
	private static int NUMBER_LISTENERES_TO_SPEECH_QUERY = 0;
	private int listenToSpeechQuery;
	ReceiverSpeechQuery receiverSpeechQuery;

	public RowSearch(Context context) {
		super(context);
		init(null);
	}
	public RowSearch(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(attrs);
	}

	public RowSearch(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(attrs);
	}
	private void init(AttributeSet attrs){
		LayoutInflater.from(getContext()).inflate(R.layout.view_row_search, this);
		rowSearch = (EditText)findViewById(R.id.row);
		search = (ImageView)findViewById(R.id.search);
		microphone = (ImageView)findViewById(R.id.microphone);
		flipperSearch = (ViewFlipper)findViewById(R.id.flipperSearch);
		Typeface tf = Typeface.createFromAsset(getContext().getAssets(),"fonts/robotoLight.ttf");
		rowSearch.setTypeface(tf,Typeface.NORMAL); 
		initListeners();

		Animation in = AnimationUtils.loadAnimation(getContext(), R.anim.push_right_and_fade_in);
		Animation out = AnimationUtils.loadAnimation(getContext(), R.anim.push_left_and_fade_out);
		flipperSearch.setInAnimation(in);
		flipperSearch.setOutAnimation(out);

		if(attrs != null){
			TypedArray a = getContext().obtainStyledAttributes(attrs,
					R.styleable.RowSearch);

			final int N = a.getIndexCount();
			for (int i = 0; i < N; ++i)
			{
				int attr = a.getIndex(i);
				switch (attr)
				{
				case R.styleable.RowSearch_textColor:
					int textColor = a.getInt(attr,R.color.black);
					rowSearch.setTextColor(textColor);
					break;
				case R.styleable.RowSearch_textSize:
					int textSize = a.getInt(attr,12);
					rowSearch.setTextSize(textSize);
					break;
				case R.styleable.RowSearch_searchImage:
					int drawableImageSearch = a.getResourceId(attr,R.drawable.regular_search);
					search.setImageDrawable(getResources().getDrawable(drawableImageSearch));
					break;
				case R.styleable.RowSearch_microphoneImage:
					int drawableImageMicrophone = a.getResourceId(attr,R.drawable.regular_microphone);
					microphone.setImageDrawable(getResources().getDrawable(drawableImageMicrophone));
					break;
				case R.styleable.RowSearch_searchImageBackground:
					int drawableBackground = a.getResourceId(attr,R.drawable.search_background);
					flipperSearch.setBackgroundResource(drawableBackground);
					break;
				case R.styleable.RowSearch_searchBackground:
					int drawable = a.getResourceId(attr,R.drawable.row_search_background);
					rowSearch.setBackgroundResource(drawable);
					break;
				case R.styleable.RowSearch_searchHint:
					int hint = a.getResourceId(attr,0);
					rowSearch.setHint(hint);
					break;
				case R.styleable.RowSearch_searchColorHint:
					int colorHint = a.getResourceId(attr,0);
					rowSearch.setHintTextColor(getResources().getColor(colorHint));
					break;
				}
			}
			a.recycle();
		}
	}
	private void initListeners(){
		rowSearch.setOnEditorActionListener(this);
		rowSearch.setOnTouchListener(new SlidListener(3, this, SlidDirection.RIGHT,SlidDirection.LEFT));
		search.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				slidListener(true);
			}
		});
		microphone.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent i = new Intent(getContext(),SpeechQuery.class);
				i.putExtra(SpeechQuery.RETURN_TO, listenToSpeechQuery);
				getContext().startService(i);
			}
		});
		rowSearch.addTextChangedListener(new TextWatcher() {

			boolean isStartUp = true;
			
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				// TODO Auto-generated method stub

			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub

			}

			@Override
			public void afterTextChanged(Editable s) {
				if(s.toString().isEmpty()){
					if(flipperSearch.getChildAt(
							flipperSearch.getDisplayedChild()).getId() != R.id.microphone){
						flipperSearch.setDisplayedChild(0);
					}
				}
				else{
					if(flipperSearch.getChildAt(
							flipperSearch.getDisplayedChild()).getId() != R.id.search){
						flipperSearch.setDisplayedChild(1);
						isStartUp = false;
					}
				}
				if(onTextChangedListener != null && !isStartUp){
					onTextChangedListener.textChanged(rowSearch.getText().toString());
				}
			}
		});

	}
	public void registerSpeechQuery(){
		if(receiverSpeechQuery != null){
			unregisterSpeechQuery();
		}
		receiverSpeechQuery = new ReceiverSpeechQuery();
		getContext().registerReceiver(receiverSpeechQuery, new IntentFilter(SpeechQuery.RESULTS_SPEECH_READY));
		NUMBER_LISTENERES_TO_SPEECH_QUERY++;
		listenToSpeechQuery = NUMBER_LISTENERES_TO_SPEECH_QUERY;
	}
	public void unregisterSpeechQuery(){
		if(receiverSpeechQuery != null){
			getContext().unregisterReceiver(receiverSpeechQuery);
			NUMBER_LISTENERES_TO_SPEECH_QUERY--;
		}
	}
	public void setOnRunSearchListener(OnRunSearchListener runSearchListener){
		this.onRunSearchListener = runSearchListener;
	}
	public void setOnTextChangedListener(OnTextChangedListener onTextChangedListener) {
		this.onTextChangedListener = onTextChangedListener;
	}
	public String getValue() {
		return rowSearch.getText().toString();
	}
	public void setValue(String text) {
		rowSearch.setText(text);
	}
	public String getLastSearch() {
		return lastSearch;
	}
	@Override
	public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
		outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI;
		return super.onCreateInputConnection(outAttrs);
	}
	@Override
	public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
		slidListener(true);
		return true;
	}
	@Override
	public void startedSlid(View v) {
		this.setFocusable(true);
		requestFocus();
	}
	@Override
	public void finishedSlid(View v,SlidDirection slidDirection) {
		if(slidDirection == SlidDirection.RIGHT){
			slidListener(true);
		}
		else if(slidDirection == SlidDirection.LEFT){
			slidListener(false);
		}
	}

	private void slidListener( boolean isRightSlid){
		if(isRightSlid){
			lastSearch = getValue();
			if(getValue().isEmpty()){
				rowSearch.setHint(R.string.writeSomethingHere);
			}
			if(onRunSearchListener != null){
				onRunSearchListener.search(rowSearch.getText().toString());
			}
		}
		else{
			rowSearch.setText("");
		}
		// when user slid to right or press on search in keyboard hide keyboard
		// when user slid to left open keyboard
		Utilities.showKeyboard(!isRightSlid,this);
	}
	public class ReceiverSpeechQuery extends BroadcastReceiver{
		@Override
		public void onReceive(Context context, Intent intent) {
			int returnTo = intent.getIntExtra(SpeechQuery.RETURN_TO, 0);
			if(returnTo == listenToSpeechQuery){
				String[] results = intent.getExtras().getStringArray(SpeechQuery.GET_RESULTS);
				rowSearch.setText(results[0]);
				slidListener(true);
			}
		}
	}

	@Override
	public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);
		rowSearch.setEnabled(enabled);
		search.setEnabled(enabled);
		microphone.setEnabled(enabled);
	}
	public interface OnRunSearchListener{
		void search(String query);
	}
	public interface OnTextChangedListener{
		void textChanged(String text);
	}
	public void clear() {
		rowSearch.setText("");
	}

}
